const axios = require('axios');
const crypto = require('crypto');
const config = require('@config/wx');

// 生成随机字符串
const generateNonceStr = () => {
  return Math.random().toString(36).substr(2, 15);
};

// 生成签名
const generateSign = (params, apiKey) => {
  const sortedParams = Object.keys(params)
    .filter(key => params[key] !== undefined && params[key] !== '')
    .sort()
    .map(key => `${key}=${params[key]}`)
    .join('&');

  const stringSignTemp = `${sortedParams}&key=${apiKey}`;
  return crypto.createHash('md5').update(stringSignTemp).digest('hex').toUpperCase();
};

// 创建微信支付订单
exports.createWxPayment = async ({
  openid,
  out_trade_no,
  total_fee,
  body
}) => {
  const params = {
    appid: config.miniapp.appId,
    mch_id: config.payment.mchId,
    nonce_str: generateNonceStr(),
    body,
    out_trade_no,
    total_fee,
    spbill_create_ip: '127.0.0.1',
    notify_url: config.payment.notifyUrl,
    trade_type: config.payment.tradeType,
    openid
  };

  // 生成签名
  params.sign = generateSign(params, config.payment.apiKey);

  // 将参数转换为XML
  const xmlData = Object.keys(params)
    .map(key => `<${key}>${params[key]}</${key}>`)
    .join('');
  const xml = `<xml>${xmlData}</xml>`;

  // 调用微信支付统一下单接口
  const { data } = await axios.post(
    'https://api.mch.weixin.qq.com/pay/unifiedorder',
    xml,
    {
      headers: { 'Content-Type': 'text/xml' }
    }
  );

  // 解析返回的XML数据
  const result = {};
  const xml2js = require('xml2js');
  await xml2js.parseString(data, { trim: true }, (err, parsed) => {
    if (err) {
      throw new Error('解析支付结果失败');
    }
    Object.keys(parsed.xml).forEach(key => {
      result[key] = parsed.xml[key][0];
    });
  });

  if (result.return_code !== 'SUCCESS' || result.result_code !== 'SUCCESS') {
    throw new Error(result.err_code_des || result.return_msg || '支付失败');
  }

  // 生成支付参数
  const payParams = {
    timeStamp: Math.floor(Date.now() / 1000).toString(),
    nonceStr: generateNonceStr(),
    package: `prepay_id=${result.prepay_id}`,
    signType: 'MD5'
  };

  // 生成支付签名
  const paySign = generateSign({
    appId: config.miniapp.appId,
    timeStamp: payParams.timeStamp,
    nonceStr: payParams.nonceStr,
    package: payParams.package,
    signType: payParams.signType
  }, config.payment.apiKey);

  return {
    ...payParams,
    paySign
  };
}; 